#ifndef _GUIWINDOW_H
#define _GUIWINDOW_H
#include "GlWindow.h"
#include <FL/Fl_Choice.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Float_Input.H>



static int mFsChoices[] = {44100, 1000, 10000, 20000, 44100};
static int mTChoices[]  = {   1,     2,     3};

enum WaveformChoices {
  Sine, Triangle, Square, Random, Flat 
};


class GuiWindow : public Fl_Window {
  //segmentation fault definitly caused by fl_gl_window, but I can't locate the root of the problem
  GlWindow* gwin;
  Fl_Choice* mFsChoice;
  Fl_Choice* mTChoice;
  Fl_Button* mPlayButton;
  Fl_Button* mStopButton;
  Fl_Button* mResetButton;
  
  Fl_Choice* mWaveformChoice;
  Fl_Input* mWaveformFsInput;
  Fl_Button* mWaveformInsertButton;
  
  Waveform* mWfm;
  AudioPlayer audio;

  // could have a single button callback, and pass a button specifying enum value
  
  
  // PlayButton
  void playButton(void) {
    audio.stopAudio();

    printf("Play Button Pressed!\n");
    printf("Samplerate: %d\n", (*mWfm).getSampleRate());
    audio.setAudio(*mWfm);
    audio.startAudio();
  }
  
  static void playButton(Fl_Widget* w, void*userdata) {
    GuiWindow* win = (GuiWindow*)userdata;
    win->playButton();
  }
  
  // StopButton
  void stopButton(void) {
    printf("Stop Button Pressed!\n");
    audio.stopAudio();
  }
  
  static void stopButton(Fl_Widget* w, void*userdata) {
    GuiWindow* win = (GuiWindow*)userdata;
    win->stopButton();
  }

  // ResetButton
  void resetButton(void) {
    printf("Reset Button Pressed!\n");
    mWfm->reset();
    gwin->redraw();
  }

  static void resetButton(Fl_Widget* w, void*userdata) {
    GuiWindow* win = (GuiWindow*)userdata;
    win->resetButton();
  }


  // WaveformInsertButton
  void waveformInsertButton(void) {
    printf("value: %f, Sine: %d\n",atof(mWaveformFsInput->value()), Sine );
    int choice = mWaveformChoice->value();
    float freq = atof(mWaveformFsInput->value());
    float l = gwin->mSelect.getLeft() * mWfm->size();
    float r = gwin->mSelect.getRight() * mWfm->size();

    switch( choice ) {
    case Sine: {
      mWfm->insertSine( l, r, freq );
      break;
    }
    case Triangle:{
      mWfm->insertTriangle( l, r, freq );
      break;
    }
    default: 
	printf("Unrecognized waveform requested, eek!\n");
    }
    gwin->redraw();
    printf("WaveformInsert Button Pressed!\n");
  }

  static void waveformInsertButton(Fl_Widget* w, void*userdata) {
    GuiWindow* win = (GuiWindow*)userdata;
    win->waveformInsertButton();
  }

  // FsChoiceDrop
  void fsChoiceDrop(void) {
    printf("FsChoice Drop Pressed!\n");
  }

  static void fsChoiceDrop(Fl_Widget* w, void*userdata) {
    GuiWindow* win = (GuiWindow*)userdata;
    win->fsChoiceDrop();
  }

  // TChoiceDrop
  void tChoiceDrop(void) {
    printf("TChoice Drop Pressed!\n");
  }

  static void tChoiceDrop(Fl_Widget* w, void*userdata) {
    GuiWindow* win = (GuiWindow*)userdata;
    win->tChoiceDrop();
  }



 public:

  ~GuiWindow ( void ) {
    delete mFsChoice;
    delete mTChoice;
    delete mPlayButton;
    delete mResetButton;
    
    delete mWaveformChoice;
    delete mWaveformFsInput;
    delete mWaveformInsertButton;
    delete gwin;
    delete mWfm;
  } 

  GuiWindow ( int X,int Y,const char*L=0) : Fl_Window(X,Y,L) { 
        
    //add a dropdown to select sample rate
    mFsChoice = new Fl_Choice(210, h()-55, 100, 20, "Sample Rate");
    mFsChoice->add(" 100 | 1000 | 10000 ");
    mFsChoice->value(0);
    mFsChoice->callback( fsChoiceDrop, (void*)this);
    
    //add a dropdown to select sample rate
    mTChoice = new Fl_Choice(210, h()-35, 100, 20, "Duration");
    mTChoice->add(" .25 | .5 | 1 | 2 | 3 ");
    mTChoice->value(0);
    mTChoice->callback( tChoiceDrop, (void*)this);

    //make a play button
    mPlayButton = new Fl_Button(10, h()-65, 100, 20, "Play");
    mPlayButton->callback(playButton, (void*)this);
    
    //make a stop button
    mStopButton = new Fl_Button(10, h()-45, 100, 20, "Stop");
    mStopButton->callback(stopButton, (void*)this);

    // make a reset button
    mResetButton = new Fl_Button(10, h()-25, 100, 20, "Reset");
    mResetButton->callback(resetButton, (void*)this);

    // now make the drop-downs and button for the waveform insertion stuff.
    mWaveformChoice = new Fl_Choice(390, h()-45, 100, 20, "waveform");
    mWaveformChoice->add(" Sine | Triangle | Square | Random | Flat ");
    mWaveformChoice->value(0);
    
    mWaveformFsInput = new Fl_Float_Input(390, h()-25, 100, 20, "Hz");
    mWaveformFsInput->value("0.0");
    
    mWaveformInsertButton = new Fl_Button(390, h()-65, 100, 20, "Insert");    
    mWaveformInsertButton->callback(waveformInsertButton, (void*)this);
    
    mWfm = new Waveform( mTChoices[0], mFsChoices[0] );
    printf("GuiWindow size: %d\n", mWfm->size());
    //put a glwindow in as part of my larger gui
    gwin = new GlWindow(10, 10, w()-20, h()-80, mWfm);

    end();
  }
};

#endif
